package com.gitee.cui.netty.decoder;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 通过继承ByteToMessageDecoder解析器来实现正确读取字符串内容的程序
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021/10/22 21:03
 **/
public class StringIntegerHeaderDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 先读字符串长度，如果字节长度不够，直接返回
        if (in.readableBytes() < 4) {
            return;
        }
        // 在真正读取数据之前，先暂存读取数据的初始位置，防止后续读取字符串内容因长度不够需要重新读取时，重置到初始位置
        in.markReaderIndex();
        // 读取字符串长度
        int length = in.readInt();
        // 如果接下来可读的数据长度，小于字符串长度，则不读取
        if (in.readableBytes() < length) {
            // 重置初始化读取位置
            in.resetReaderIndex();
            return;
        }
        byte[] array = new byte[length];
        in.readBytes(array, 0, length);
        out.add(new String(array, StandardCharsets.UTF_8));
    }
}
